#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>


/* ************************* CONECTARSE **********************
 Es NO blokeante
 Hara 1 intento por conectarse a Partir de Un puerto y un IP, 
 Escribe en socketaAsociar
 socketaasociar es una variable limpia sin la llamada a socket
 
 TOMA puertoDestino IpDestino
 ESCRIBE en SocketAasociar con el Socket conectado, listo para ser usado
 DEVUELVE
 OK			---> Devuelve  0
 Error en Socket()	---> Devuelve -1
 Error en Connect()	---> Devuelve -2
*/

int conectarse(int* puertodestino, char* ipdestino,int* socketaasociar);

 
/* ********************** ESCUCHARYACEPTARVARIAS ***********************
 
   Escucha y acepta una cantidad (tomada como argumento) de conexiones entrantes.
   
   TOMA  mi puerto, mi ip , cantidad de conecciones a aceptar y tiempoMaximoDeEspera
   ESCRIBE los Sockets Entrantes en socketConectados, y sus respectivos datos en entrantesDir.
   	   por ORDEN DE LLEGADA DE LAS CONEXIONES

	NOTA: 	Es importante haber reservado memoria para socketConectados y entrantesDir
	      
		Recomendado inicio de procesos con X cantidad de conexiones con otros procesos
 	      	
		Para Saber La identidad De los procesos entrantes, se puede preestablecer el orden
	      	de las conecciones, se pueden obtener los datos desde entrantesDir, o mandarle
	      	un mensaje a cada conexion nueva para que se identifique.
	      	
		Si tiempo<0 La funcion Se blokeara y esperara hasta aceptar toda la cantidad
	      	Si tiempo==0 La funcion Comprobara y aceptara las que halla
		Si tiempo>0 Obviamente es el tiempo maximo de espera por conexiones nuevas
	      
 * Devuelve  >0 : Conexiones Conectadas
 * Devuelve -1 : Error en socket()
 * Devuelve -2 : Error en Bind()
 * Devuelve -3 : Error en listen()
 * Devuelve -4 : Error en Accept()
 * Devuelve -5 : Error No evaluado En Select()
 * Devuelve -6 : Error no Evaluado
 */


int escucharyaceptarvarias(int* mipuerto,char* miip,int cantidad,int tiempo,
		int* socketconectados, struct sockaddr_in* entrantesdir);

int escucharyaceptarvarias2(int,int cantidad,int tiempo,
		int* socketconectados, struct sockaddr_in* entrantesdir);

int crearSocketEscucha(int *,char*,int*);

/********************************* MANDARMENSAJECHAR ************************************/

/*  	TOMA una cadena de maximo 254 Caracteres LA EMPAQUETA (anteponiendo un char "tamanio")
 *  	y la envia a SOCKETDESTINO
 *  	Devuelve -1: Error De memoria
	Devuelve -2: Error en el envio del mensaje
	Devuelve  0: OK*/

int mandarMensajeChar(char* mensaje,int* socketdestino);




/* *************** LEER MENSAJE EMPAQUETADO ******************** */

int leerMensajeEmpaquetado(char*,int);



	
/* ************************** REVISAR CONEXIONES **************************************** */
/*seg=-1--> Blok, seg=0--> Instantanea, seg>0-->timeVal*/
/*-1--> vectorConexiones Vacia, 1--> OK, 0 timeValExpirado, -2 Algo Raro*/
int revisarConexiones(int vectorConexiones[],int tamanio,int segDeEsperaMaxima,int *socketAct);


	
/**************FUNCION PARA INICIALIZAR EL CONJUNTO DE CONEXIONES*********************/
int inicializarConjuntoDeConexiones(int vectorConexiones[],int tamanio);

	
	
/* ***************FUNCION PARA AGREGAR CONEXIONES A UN CONJUNTO******************** */
/* , 0--> vector LLENO, 1--> OK*/
int agregarConexion(int vectorConexiones[],int tamanio, int socket);


/* ********* FUNCION PARA VERIFICAR EXISTENCIA DE UN SOCKET EN EL CONJUNTO ****************** */
/* 1--> Encuentra, 0 No Encuentra*/
int existeConexion(int vectorConexiones[],int tamanio,int socket);



/* ************ FUNCION PARA ELIMAR UN SOCKET DEL CONJUNTO ************************ */
/* 1--> OK, 0 No lo encontro*/
int eliminarConexion(int vectorConexiones[],int tamanio,int socket);

/* ************ FUNCION PARA OBTENER IP,PUERTO,HOST A PARTIR DE UN SOCKET ********* */
/*ERRROR --> -2*/
int descubrirConexion(int,char*,char*,char*);






